home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
array.lha
/
array
/
COPYNOTE
< prev
next >
Wrap
Text File
|
1993-08-08
|
3KB
|
97 lines
s noted in the README file, the current version of the array class
oes not have a copy-constructor, although the first version had one.
he first version was clearly wrong, and I thank Tom Cargill for
ointing this out.
have not been able to make the copy-constructor work properly with
y compiler (AT&T 3.0.1), although I know what I would like to do. If
ou can find a useful work-around, or have a compiler that may handle
he approach described below, please let me know. As always, I will
ppreciate your comments.
he code examples below are based on the declaration of Array<T>, see
rray.H for details.
orrect behaviour of copy-constructor.
my view, the only correct behaviour for the array copy-constructor
s to create copies of each element with the copy-constructor of the
lement type. In particular, I think the following implementation is
rong:
emplate <class T>
rray<T>::Array(const Array<T>& a)
: low(a.low), sz(a.sz)
data = new T[sz];
assert(data != 0);
for (unsigned i = 0; i < sz; i++)
data[i] = a.data[i];
t first creates an array, initializing every element with the default
onstructor, and then uses the assignment operator to change the
alues of the new array elements. Of course, this approach works well
or simple element types, such as, ints and doubles.
correct copy-constructor.
he original version had a copy-constructor that tried very hard to
et the initialization right, and that part was in fact correct. The
rick is to allocate the right amount of space without doing the
efault initialization, and then do the element-wise initialization:
emplate <class T>
rray<T>::Array(const Array<T>& a)
: low(a.low), sz(a.sz)
data = (T*) new char[sizeof(T)*sz];
assert(data != 0);
for (unsigned i = 0; i < sz; i++)
new (data+i) T(a.data[i]);
hat piece of code must then be matched by an appropriate destructor,
hich calls the destructor for each element:
emplate <class T>
rray<T>::~Array()
for (unsigned i = 0; i < sz; i++)
data[i].T::~T();
delete (char *) data;
nfortunately, Cfront 3.0.1 does not seem to recognize "T::~T" in a
emplate, and now I have run out of ideas! Maybe I just got it all
rong, and in that case I would be terribly grateful for your advice.
riginal error.
om Cargill found a related bug in my original code: that I mixed
vector new" and "plain new" in my class. The default constructor
llocated a vector of Ts with
new T[sz]
hile the copy-constructor allocated a raw piece of memory with
(T*) new char[sizeof(T)*sz]
hich was then initialized. However, the destructor assumed vector
llocation:
delete [] data;
hat happens is that you will run the destructors if the array was
ade with the default constructor, but not if the array was made with
he copy-constructor. The behaviour depends on how Cfront implements
ew of vectors.
he solution is to only allocate raw storage (also in the default
onstructor) and use explicit construction/destruction of the
lements.